from django.shortcuts import render, get_object_or_404
from comicinfo.serializers import ComicInfoSerializer, ComicKindSerializer
from rest_framework import mixins
from rest_framework.viewsets import GenericViewSet
from comicinfo.filters import ComicInfoFilter
from .models import ComicInfo, ComicDetail, ComicIndex, ComicKind
from django.core.paginator import Paginator
from django.views.generic import View
from utils.mixin import LoginRequiredMixin
from django.core.cache import cache
from django_redis import get_redis_connection
from user_operations.models import Comments


class ComicInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
    """
    list:
        查看所有漫画
    retrieve:
        查看单部漫画
    """
    queryset = ComicInfoSerializer.Meta.model.objects.all().order_by('id')
    serializer_class = ComicInfoSerializer
    # ⬇ 分类筛选
    filterset_class = ComicInfoFilter


class ComicKindViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
    """
    list:
        查看所有分类
    retrieve:
        查看单个分类
    """
    queryset = ComicKindSerializer.Meta.model.objects.all().order_by('id')
    serializer_class = ComicKindSerializer


def index(request):
    # 设置缓存
    context = cache.get('index_page_data')

    # 判断是否获取到缓存数据
    if context is None:
        kinds = ComicKind.objects.all()
        books = ComicInfo.objects.all().order_by('id')
        passionate_books = ComicInfo.objects.filter(kind=1)
        read_num = ComicInfo.objects.values_list('book_name', 'popularity')
        paginator = Paginator(books, 48)
        b = dict(read_num)

        context = {'kinds': kinds, 'books': books, 'passionate_books': passionate_books}

        cache.set('index_page_data', context, 3600)

    return render(request, 'index.html', context)


def lists(request, pk, pnum):
    kinds = ComicKind.objects.all()
    if pk == '':
        pk = 1
    else:
        pk = int(pk)

    comickind_id = pk
    books = ComicInfo.objects.filter(kind=comickind_id)
    a = len(books)
    paginator = Paginator(books, 30)
    if pnum == '':
        pnum = 1
    else:
        pnum = int(pnum)
    page = paginator.page(pnum)

    active = 'active'

    return render(request, 'list.html', {
        'kinds': kinds, 'books': books,
        'page': page, 'comickind_id': comickind_id,
        'active': active
    })


def test(request):
    kinds = ComicKind.objects.all()
    books = ComicInfo.objects.all().order_by('id')
    passionate_books = ComicInfo.objects.filter(kind=1)
    read_num = ComicInfo.objects.values_list('book_name', 'popularity')
    b = dict(read_num)

    return render(request, 'index01.html', {
        'kinds': kinds, 'books': books,
        'passionate_books': passionate_books,
    })


def single(request, pk):
    comic = get_object_or_404(ComicInfo.objects.filter(id=pk))

    comicindex = ComicIndex.objects.filter(belongto_comic_id=pk)

    kind_id = ComicKind.objects.get(kind_comic=pk)

    kinds = ComicKind.objects.all()

    # 获取所有评论
    comments = Comments.objects.filter(comic=pk).order_by('-time')

    return render(request, 'single.html', {
        'comic': comic, 'comicindex': comicindex,
        'kind_id': kind_id, 'kinds': kinds,
        'comments': comments
    })


class ComicView(LoginRequiredMixin, View):

    def get(self, request, chapter_id, pnum):

        # 获取请求的章节号
        chapter = ComicIndex.objects.get(id=chapter_id)
        # 获取到请求的对应漫画
        book_id = chapter.belongto_comic_id
        comic_book = ComicInfo.objects.get(id=book_id)

        # 获取该本漫画所有章节
        chapters = ComicIndex.objects.filter(belongto_comic_id=book_id)
        # 获取到本章节的上一章和下一章
        next_num, pre_num = nextAndpre(chapters, chapter)
        next_chapter = chapters[next_num]
        pre_chapter = chapters[pre_num]

        # 获取图片
        comic_imgs = ComicDetail.objects.filter(belongto_catalog_id=chapter_id)

        # 分页,每页显示十张图
        paginator = Paginator(comic_imgs, 10)
        # 获取分页内容
        if pnum == '':
            pnum = 1
        else:
            pnum = int(pnum)
        page = paginator.page(pnum)

        # 获取用户漫画浏览记录
        user = request.user
        # 连接 redis
        con = get_redis_connection('default')
        # 用户id + 浏览记录 绑定 放入 redis
        history_key = 'history_%d' % user.id
        comic_ids = con.lrange(history_key, 0, 4)

        comics_list = []

        # 遍历漫画，添加到列表
        for comic_id in comic_ids:
            comic = ComicInfo.objects.get(id=comic_id)
            comics_list.append(comic)

        return render(request, 'comic.html',
                      {'comic_imgs': comic_imgs,
                       'page': page, 'comic_book': comic_book,
                       'chapter': chapter, 'pre_chapter': pre_chapter,
                       'next_chapter': next_chapter,
                       'comics_list': comics_list,
                       })


def show_comic(request, chapter_id, pnum):
    # 获取请求的章节号
    chapter = ComicIndex.objects.get(id=chapter_id)
    # 获取到请求的对应漫画
    book_id = chapter.belongto_comic_id
    comic_book = ComicInfo.objects.get(id=book_id)

    # 获取该本漫画所有章节
    chapters = ComicIndex.objects.filter(belongto_comic_id=book_id)
    # 获取到本章节的上一章和下一章
    next_num, pre_num = nextAndpre(chapters, chapter)
    next_chapter = chapters[next_num]
    pre_chapter = chapters[pre_num]

    # 获取图片
    comic_imgs = ComicDetail.objects.filter(belongto_catalog_id=chapter_id)

    # 分页,每页显示十张图
    paginator = Paginator(comic_imgs, 10)
    # 获取分页内容
    if pnum == '':
        pnum = 1
    else:
        pnum = int(pnum)
    page = paginator.page(pnum)

    return render(request, 'comic.html',
                  {'comic_imgs': comic_imgs,
                   'page': page, 'comic_book': comic_book,
                   'chapter': chapter, 'pre_chapter': pre_chapter,
                   'next_chapter': next_chapter,
                   })


# 专门处理上一章和下一章的函数
def nextAndpre(chapters, chapter):
    for i in range(len(chapters)):
        if chapters[i] == chapter:
            next_num = i - 1
            pre_num = i + 1
            if next_num < 0:
                next_num = 0
            if pre_num > len(chapters) - 1:
                pre_num = len(chapters) - 1

            return next_num, pre_num
